package com.dyh.quickdemozwei;

import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;


@Slf4j
public class TestPallerStream {


    ThreadPoolExecutor poolExecutor;
    {
        this.poolExecutor = new ThreadPoolExecutor(3,6,
                300, TimeUnit.SECONDS,
//                new SynchronousQueue<>(),
                new LinkedBlockingQueue<>(200),
                new ThreadFactoryBuilder().setNameFormat("pool-%d").build(),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }



    List<CompletableFuture> gentListFuture(List<Integer> list){
//        Function<Integer,CompletableFuture> fc = e->CompletableFuture.runAsync(()->consumer.accept(e),poolExecutor);
//        return list.stream().map(e->poolExecutor.submit(()->consumer.accept(e))).collect(Collectors.toList());

        return list.stream().map(e->CompletableFuture.runAsync(()->consumer.accept(e),poolExecutor))
                .collect(Collectors.toList());
    }

    /*提交完任务已经在池子里了*/
    @Test public void test2() throws InterruptedException {
        log.info("datas1 开始");
        List<Integer> datas1 = Lists.newArrayList(1,2,3,4,5);

        log.info("gent1 开始");
        CompletableFuture datas1AllDone =
                CompletableFuture.allOf(gentListFuture(datas1).toArray(new CompletableFuture[0]) );
        log.info("gent1 结束");

        log.info("中途休眠开始");
        Thread.sleep(2000L);
        log.info("中途休眠结束");


        log.info("datas2 开始");

        List<Integer> datas2 = Lists.newArrayList(6,7,8,9);

        log.info("gent2 开始");
        CompletableFuture datas2AllDone =
                CompletableFuture.allOf(gentListFuture(datas2).toArray(new CompletableFuture[0]) );
        log.info("gent2 结束");

        log.info("datas2 join 开始");
        datas2AllDone.join();
        log.info("datas2 join 结束");

        log.info("datas1 join 开始");
        datas1AllDone.join();
        log.info("datas1 join 结束");

        System.out.println();
    }


    @Test public void test1(){
        log.info("datas1 开始");
        List<Integer> datas1 = Lists.newArrayList(1,2,3,4,5);
        CompletableFuture datas1AllDone =
                CompletableFuture.allOf(gentListFuture(datas1).toArray(new CompletableFuture[0]) );
        datas1AllDone.join();
        log.info("datas1 结束");
        //提供泛型
//                        .thenApply(e-> uploadFutures.stream().map(CompletableFuture::join)
//                                .collect(Collectors.toList())//写作join 读作立即完成
//                        );


        log.info("datas2 开始");

        List<Integer> datas2 = Lists.newArrayList(6,7,8,9);
        CompletableFuture datas2AllDone =
                CompletableFuture.allOf(gentListFuture(datas2).toArray(new CompletableFuture[0]) );
        datas2AllDone.join();
        log.info("datas2 结束");

        System.out.println();
    }

    @Test public void test(){

        List<Integer> datas1 = Lists.newArrayList(1,2,3,4,5);
        List<Integer> datas2 = Lists.newArrayList(6,7,8,9);

        log.info("fullStart1");
        datas1.parallelStream().forEach(consumer);
        log.info("fullEnd1");

        log.info("fullStart2");
        datas2.parallelStream().forEach(consumer);
        log.info("fullEnd2");
    }


    Consumer<Integer> consumer =e->{

        log.info("{}-开始-{}",Thread.currentThread().getName(),e);
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        log.info("{}-结束-{}",Thread.currentThread().getName(),e);

    };


    @Test
    public void testSingle(){
        List<Integer> datas = Lists.newArrayList(1,2,3,4,5);
        log.info("fullStart");
        datas.stream().forEach(consumer);
        log.info("fullEnd");

        System.out.println();
    }

    @Test
    public void testMulti(){
        List<Integer> datas = Lists.newArrayList(1,2,3,4,5);
        log.info("fullStart");
        datas.parallelStream().forEach(consumer);
        log.info("fullEnd");

        System.out.println();
    }
}
